// Decompiled by Jad v1.5.8e2. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://kpdus.tripod.com/jad.html
// Decompiler options: packimports(3) fieldsfirst ansi space 
// Source File Name:   AGateway.java

package cn.sendsms;

import java.io.IOException;
import java.util.List;
import org.apache.log4j.Logger;

// Referenced classes of package cn.sendsms:
//			Queue, OutboundMessage, GatewayException, TimeoutException, 
//			MessageProtocols, GatewayStatuses, MessagePriorities, IInboundMessageNotification, 
//			IOutboundMessageNotification, ICallNotification, MessageClasses, InboundMessage, 
//			DeliveryStatuses, FailureCauses

public abstract class AGateway
{
	private class MessageQueueManager
		implements Runnable
	{

		public Object get()
		{
			if (highQ.size() > 0)
				return highQ.get();
			if (normalQ.size() > 0)
				return normalQ.get();
			if (lowQ.size() > 0)
				return lowQ.get();
			else
				return null;
		}

		public void run()
		{
			logInfo("Starting Queue Manager");
			try
			{
				if (started)
					do
					{
						OutboundMessage msg = (OutboundMessage)get();
						if (msg == null)
						{
							Thread.sleep(queueDelay);
						} else
						{
							if (!sendMessage(msg))
							{
								if (msg != null)
									if (msg.getRetryCount() < queueRetries)
									{
										logInfo("Reinserting message to queue.");
										msg.incrementRetryCount();
										queueMessage(msg);
									} else
									{
										if (getOutboundNotification() != null)
											getOutboundNotification().process(gtwId, msg);
										logInfo("Maximum number of retries (" + queueRetries + ") exceeded.");
										msg.setFailureCause(FailureCauses.UNKNOWN);
									}
							} else
							if (getOutboundNotification() != null)
								getOutboundNotification().process(gtwId, msg);
							Thread.sleep(queueDelay);
						}
					} while (true);
			}
			catch (InterruptedException e)
			{
				logInfo("Interrupting queue.");
			}
			catch (Exception e)
			{
				logInfo("Interrupting queue.");
			}
			logInfo("QueueManager stopped");
		}

		public MessageQueueManager()
		{
			super();
		}
	}

	static class Statistics
	{

		public int inbound;
		public int outbound;

		public Statistics()
		{
			inbound = 0;
			outbound = 0;
		}
	}

	static class GatewayAttributes
	{

		public static final int SEND = 1;
		public static final int RECEIVE = 2;
		public static final int CUSTOMFROM = 4;
		public static final int BIGMESSAGES = 8;
		public static final int WAPSI = 16;
		public static final int PORTADDRESSING = 32;
		public static final int FLASHSMS = 64;
		public static final int DELIVERYREPORTS = 128;

		GatewayAttributes()
		{
		}
	}


	protected boolean started;
	protected String gtwId;
	protected int attributes;
	protected boolean inbound;
	protected boolean outbound;
	protected Logger logger;
	protected MessageProtocols protocol;
	protected IInboundMessageNotification inboundNotification;
	protected IOutboundMessageNotification outboundNotification;
	protected ICallNotification callNotification;
	protected Statistics statistics;
	protected String from;
	protected int deliveryErrorCode;
	protected int queueDelay;
	protected int queueRetries;
	protected Thread queueManagerThread;
	protected Queue lowQ;
	protected Queue normalQ;
	protected Queue highQ;
	protected GatewayStatuses gatewayStatus;

	public AGateway(String id, Logger logger)
	{
		gtwId = id;
		this.logger = logger;
		started = false;
		inbound = false;
		outbound = false;
		attributes = 0;
		protocol = MessageProtocols.PDU;
		inboundNotification = null;
		outboundNotification = null;
		callNotification = null;
		from = "";
		lowQ = new Queue();
		normalQ = new Queue();
		highQ = new Queue();
		statistics = new Statistics();
		from = "";
		deliveryErrorCode = -1;
		gatewayStatus = GatewayStatuses.OK;
		queueDelay = 1000;
		queueRetries = 3;
	}

	boolean isStarted()
	{
		return started;
	}

	int getAttributes()
	{
		return attributes;
	}

	public boolean isInbound()
	{
		return inbound;
	}

	public void setInbound(boolean value)
	{
		if ((attributes & 2) != 0)
			inbound = value;
	}

	public boolean isOutbound()
	{
		return outbound;
	}

	public void setOutbound(boolean value)
	{
		if ((attributes & 1) != 0)
			outbound = value;
	}

	Logger getLogger()
	{
		return logger;
	}

	public void setProtocol(MessageProtocols protocol)
	{
		this.protocol = protocol;
	}

	public MessageProtocols getProtocol()
	{
		return protocol;
	}

	public String getGatewayId()
	{
		return gtwId;
	}

	public IInboundMessageNotification getInboundNotification()
	{
		return inboundNotification;
	}

	public void setInboundNotification(IInboundMessageNotification inboundNotification)
	{
		this.inboundNotification = inboundNotification;
	}

	public IOutboundMessageNotification getOutboundNotification()
	{
		return outboundNotification;
	}

	public void setOutboundNotification(IOutboundMessageNotification outboundNotification)
	{
		this.outboundNotification = outboundNotification;
	}

	public ICallNotification getCallNotification()
	{
		return callNotification;
	}

	public void setCallNotification(ICallNotification callNotification)
	{
		this.callNotification = callNotification;
	}

	public int getInboundMessageCount()
	{
		return statistics.inbound;
	}

	public int getOutboundMessageCount()
	{
		return statistics.outbound;
	}

	public String getFrom()
	{
		return from;
	}

	public void setFrom(String from)
	{
		this.from = from;
	}

	boolean queueMessage(OutboundMessage msg)
	{
		if (msg.getPriority() == MessagePriorities.LOW)
			lowQ.add(msg);
		else
		if (msg.getPriority() == MessagePriorities.NORMAL)
			normalQ.add(msg);
		else
		if (msg.getPriority() == MessagePriorities.HIGH)
			highQ.add(msg);
		return true;
	}

	int queueMessages(List msgList)
	{
		int count = 0;
		int i = 0;
		for (int n = msgList.size(); i < n; i++)
			if (queueMessage((OutboundMessage)msgList.get(i)))
				count++;

		return count;
	}

	void sync()
		throws IOException, InterruptedException
	{
	}

	void startGateway()
		throws TimeoutException, GatewayException, IOException, InterruptedException
	{
		queueManagerThread = new Thread(new MessageQueueManager());
		queueManagerThread.start();
		started = true;
	}

	void stopGateway()
		throws TimeoutException, GatewayException, IOException, InterruptedException
	{
		started = false;
		queueManagerThread.interrupt();
		try
		{
			queueManagerThread.join();
		}
		catch (InterruptedException e)
		{
			logInfo("Interrupted while waiting for gateway to stop.");
		}
	}

	void readMessages(List msgList, MessageClasses msgClass)
		throws TimeoutException, GatewayException, IOException, InterruptedException
	{
		throw new GatewayException("Feature not supported.");
	}

	InboundMessage readMessage(String memLoc, int memIndex)
		throws TimeoutException, GatewayException, IOException, InterruptedException
	{
		throw new GatewayException("Feature not supported.");
	}

	boolean sendMessage(OutboundMessage msg)
		throws TimeoutException, GatewayException, IOException, InterruptedException
	{
		throw new GatewayException("Feature not supported.");
	}

	int sendMessages(List msgList)
		throws TimeoutException, GatewayException, IOException, InterruptedException
	{
		int cnt = 0;
		for (int i = 0; i < msgList.size(); i++)
			if (sendMessage((OutboundMessage)msgList.get(i)))
				cnt++;

		return cnt;
	}

	boolean deleteMessage(InboundMessage msg)
		throws TimeoutException, GatewayException, IOException, InterruptedException
	{
		throw new GatewayException("Feature not supported.");
	}

	public float queryBalance()
		throws TimeoutException, GatewayException, IOException, InterruptedException
	{
		throw new GatewayException("Feature not supported.");
	}

	public boolean queryCoverage(OutboundMessage msg)
		throws TimeoutException, GatewayException, IOException, InterruptedException
	{
		throw new GatewayException("Feature not supported.");
	}

	public DeliveryStatuses queryMessage(OutboundMessage msg)
		throws TimeoutException, GatewayException, IOException, InterruptedException
	{
		return queryMessage(msg.getRefNo());
	}

	public DeliveryStatuses queryMessage(String refNo)
		throws TimeoutException, GatewayException, IOException, InterruptedException
	{
		throw new GatewayException("Feature not supported.");
	}

	public int getDeliveryErrorCode()
	{
		return deliveryErrorCode;
	}

	boolean isCapableOf(int att)
	{
		return (att & attributes) == att;
	}

	boolean conformsTo(int attrib, boolean required)
	{
		return !required || isCapableOf(attrib);
	}

	public int getQueueLoad()
	{
		return getQueueLoad(MessagePriorities.LOW) + getQueueLoad(MessagePriorities.NORMAL) + getQueueLoad(MessagePriorities.HIGH);
	}

	public int getQueueLoad(MessagePriorities priority)
	{
		if (priority == MessagePriorities.LOW)
			return lowQ.size();
		if (priority == MessagePriorities.NORMAL)
			return normalQ.size();
		if (priority == MessagePriorities.HIGH)
			return highQ.size();
		else
			return 0;
	}

	public int getQueueDelay()
	{
		return queueDelay;
	}

	public void setQueueDelay(int queueDelay)
	{
		this.queueDelay = queueDelay;
	}

	public int getQueueRetries()
	{
		return queueRetries;
	}

	public void setQueueRetries(int queueRetries)
	{
		this.queueRetries = queueRetries;
	}

	String formatLog(String message)
	{
		return "Gateway: " + gtwId + " " + message;
	}

	void logError(String message)
	{
		logger.error(formatLog(message));
	}

	void logDebug(String message)
	{
		logger.debug(formatLog(message));
	}

	void logInfo(String message)
	{
		logger.info(formatLog(message));
	}
}
